package com.ww.jmh;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.Queue;

/**
 * Scope.Group：组内共享
 * 1.规则：同一类型的状态对象在同一线程组内的所有线程间共享，不同组有独立实例
 * 2.Setup/TearDown：在组内某一个线程执行一次（每个组仅一次），组外线程不参与
 * 3.适用场景：测试“组内协作”的场景（如生产者-消费者模型，同一组内的生产者和消费者共享队列）
 */
@State(Scope.Group)
public class GroupScopeDemo {
    // 组内共享的队列（生产者和消费者共用）
    private Queue<Integer> groupQueue;

    @Setup(Level.Trial)
    public void setup() {
        groupQueue = new java.util.concurrent.ConcurrentLinkedQueue<>();
        System.out.println("Group Setup：初始化组内共享队列（组：" + Thread.currentThread().getThreadGroup().getName() + "）");
    }

    /**
     * 组内生产者
     */
    @Benchmark
    @Group("prod_cons") // 标记为“prod-cons”组
    @GroupThreads(2) // 该组内2个生产者线程
    public void producer() {
        groupQueue.add((int) System.currentTimeMillis() % 1000);
    }

    /**
     * 组内消费者
     */
    @Benchmark
    @Group("prod_cons") // 与生产者同组
    @GroupThreads(2) // 该组内2个消费者线程
    public void consumer() {
        groupQueue.poll();
    }

    public static void main(String[] args) throws RunnerException {
        Options opts = new OptionsBuilder()
                .include(GroupScopeDemo.class.getSimpleName())
                .forks(1)
                .warmupIterations(2)
                .measurementIterations(3)
                .build();
        new Runner(opts).run();
    }
}
